package com.avic.map.controller;

import com.avic.map.common.constant.MongoConstant;
import com.avic.map.common.convertor.MapCarResourceConvertor;
import com.avic.map.common.convertor.MapShipResourceConvertor;
import com.avic.map.common.convertor.MapSoldierResourceConvertor;
import com.avic.map.common.convertor.UavResourceConvertor;
import com.avic.map.common.model.HistoryPositionModel;
import com.avic.map.common.util.AssertUtil;
import com.avic.map.common.util.MapDateUitls;
import com.avic.map.common.util.ex.BizErrorCode;
import com.avic.map.common.util.ex.BizException;
import com.avic.map.common.util.lang.ServiceCallBack;
import com.avic.map.controller.request.MapCarResourceListReq;
import com.avic.map.controller.request.MapShipResourceListReq;
import com.avic.map.controller.request.MapSoldierResourceListReq;
import com.avic.map.controller.request.MapUavResourceListReq;
import com.avic.map.controller.result.GetShipHistoryPositionRes;
import com.avic.map.controller.result.GetSoldierHistoryPositionRes;
import com.avic.map.controller.result.MapCarResourceListRes;
import com.avic.map.controller.result.MapShipResourceListRes;
import com.avic.map.controller.result.MapSoldierResourceListRes;
import com.avic.map.controller.result.MapUavResourceListRes;
import com.avic.map.controller.result.MapVdmShipResourceListRes;
import com.avic.map.dal.condition.PageQueryMapCarCondition;
import com.avic.map.dal.condition.PageQueryMapShipCondition;
import com.avic.map.dal.condition.PageQueryMapSoldierCondition;
import com.avic.map.dal.condition.PageQueryMapUavCondition;
import com.avic.map.dal.model.CarResource;
import com.avic.map.dal.model.MapShipResource;
import com.avic.map.dal.model.MapUavResource;
import com.avic.map.dal.model.ShipResource;
import com.avic.map.dal.model.SingleSoldierResource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @Description
 * @Author huangsheng
 * @Date 2018/9/29 20:20
 */
@Slf4j
@RestController
@Api(tags = "应急监控界面相关接口", description = "船舶列表数据&车辆列表数据&")
public class MapController extends AbstractFacadeImpl {


    @ApiOperation(value = "其他船舶列表数据", notes = "地图左侧船舶列表数据,其他船舶数据，分页")
    @PostMapping("/vdm/ship/list")
    public MapVdmShipResourceListRes mapVdmShipResourceList(@RequestBody MapShipResourceListReq mapShipResourceListReq) {
        log.info("VDM船舶列表数据--mapShipResourceList");
        final MapVdmShipResourceListRes result = new MapVdmShipResourceListRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {

                AssertUtil.isTrue(mapShipResourceListReq.getCurrentPage() > 0,
                        BizErrorCode.PARAM_ERROR, "pageSize必须大于0");
            }

            @Override
            public void doService() throws Exception {
                PageQueryMapShipCondition pageQueryMapShipCondition =
                        new PageQueryMapShipCondition(mapShipResourceListReq.getCurrentPage(), mapShipResourceListReq.getPageSize());
                pageQueryMapShipCondition.setShipNumber(mapShipResourceListReq.getShipNumber());
                // 查询数据
                List<MapShipResource> mapShipResourceListVOS = mapShipResourceService.mapShipList(pageQueryMapShipCondition);

                result.setMapVdmShipResourceListInfos(MapShipResourceConvertor.mapShipResourceListToMapVdmShipResourceListInfoList(mapShipResourceListVOS));
                result.setTotalRecords(mapShipResourceService.mapShipListTotal(pageQueryMapShipCondition));
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "自己船舶列表数据", notes = "地图左侧船舶列表数据,自己船舶数据")
    @GetMapping("/vdo/ship/list")
    public MapShipResourceListRes mapShipResourceList(@RequestParam(value = "shipNumber", required = false) String shipNumber) {
        log.info("VDO船舶列表数据--mapShipResourceList");
        final MapShipResourceListRes result = new MapShipResourceListRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {

            }

            @Override
            public void doService() throws Exception {
                List<ShipResource> shipResources = shipResourceService.mapVdoShipRecords(shipNumber);
                result.setMapVdoShipResourceListInfos(MapShipResourceConvertor.shipResourceListToMapVdoShipResourceListInfoList(shipResources));
                result.setSuccess(true);
            }
        });
    }


//    @ApiOperation(value = "船舶当前位置信息", notes = "点击船舶列表数据用于定位船舶位置")
//    @GetMapping("ship/position/{shipNumber}")
//    public GetShipCurrentPositionRes getShipCurrentPosition(@PathVariable("shipNumber") long shipNumber) {
//        log.info("获取船舶当前位置--getShipCurrentPosition shipNumber = {}", shipNumber);
//        final GetShipCurrentPositionRes result = new GetShipCurrentPositionRes();
//        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
//            @Override
//            public void check() throws Exception {
//
//            }
//
//            @Override
//            public void doService() throws Exception {
//                AssertUtil.isTrue(redisTemplate.opsForHash().hasKey(
//                        CacheConstant.REDIS_MAP_CURRENT_SHIP_SPACE, String.valueOf(shipNumber)),
//                        BizErrorCode.SYSTEM_ERROR, "未查找当前船舶的最新坐标数据");
//
//                String shipObj = (String) redisTemplate.opsForHash().get(
//                        CacheConstant.REDIS_MAP_CURRENT_SHIP_SPACE, String.valueOf(shipNumber));
//
//                MapCommonModel mapCommonModel = objectMapper.readValue(shipObj, MapCommonModel.class);
//
//                if (null != mapCommonModel) {
//                    log.info("定位船舶时; 获取到船舶数据{}", objectMapper.writeValueAsString(mapCommonModel));
//                    result.setLatitude(mapCommonModel.getLatitude());
//                    result.setLongitude(mapCommonModel.getLongitude());
//                } else {
//                    log.info("定位船舶时; 未获取到船舶数据");
//                }
//                result.setSuccess(true);
//            }
//        });
//    }

    @ApiOperation(value = "船舶轨迹数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "shipNumber", value = "船舶编号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "queryType", value = "1 轨迹回放 2 历史轨迹，1类型，时间不用传，直接从现在的时间往前推24个小时", required = true, paramType = "query"),
            @ApiImplicitParam(name = "startTime", value = "查询的开始时间", required = true, paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "查询的结束时间", required = true, paramType = "query")
    })
    @GetMapping("ship/position/history")
    public GetShipHistoryPositionRes getShipHistoryPosition(@RequestParam String shipNumber, @RequestParam("queryType") int queryType,
                                                            @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        log.info("船舶轨迹数据--getShipHistoryPosition");
        final GetShipHistoryPositionRes result = new GetShipHistoryPositionRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {

            long startTimeLong = 0;
            long endTimeLong = 0;

            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(shipNumber, "shipNumber is not blank");
                if (queryType == 1) {
                    startTimeLong = System.currentTimeMillis() - 86400000;
                    endTimeLong = System.currentTimeMillis();
                } else if (queryType == 2) {
                    AssertUtil.isNotBlank(startTime, "开始时间不能为空");
                    AssertUtil.isTrue(AssertUtil.isValidDate(startTime), BizErrorCode.PARAM_ERROR, "开始时间不是一个标准的时间格式");
                    AssertUtil.isNotBlank(endTime, "结束时间不能为空");
                    AssertUtil.isTrue(AssertUtil.isValidDate(endTime), BizErrorCode.PARAM_ERROR, "结束时间不是一个标准的时间格式");
                    startTimeLong = MapDateUitls.convertTimeToLong(startTime);
                    endTimeLong = MapDateUitls.convertTimeToLong(endTime);
                } else {
                    throw new BizException(BizErrorCode.PARAM_ERROR, "queryType取值不正确");
                }
            }

            @Override
            public void doService() throws Exception {
                Query query = new Query();
                Criteria criteria = Criteria.where("_id").lt(endTimeLong).gte(startTimeLong);
                query.addCriteria(criteria);
                result.setHistoryPositionModels(mongoTemplate.find(
                        query, HistoryPositionModel.class, shipNumber + MongoConstant.SHIP_POSITION_HISTORY_SPACE));
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "车辆轨迹数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "carNumber", value = "车辆编号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "queryType", value = "1 轨迹回放 2 历史轨迹，1类型，时间不用传，直接从现在的时间往前推24个小时", required = true, paramType = "query"),
            @ApiImplicitParam(name = "startTime", value = "查询的开始时间", required = true, paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "查询的结束时间", required = true, paramType = "query")
    })
    @GetMapping("car/position/history")
    public GetShipHistoryPositionRes getCarHistoryPosition(@RequestParam String carNumber, @RequestParam("queryType") int queryType,
                                                           @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        log.info("车辆轨迹数据--getCarHistoryPosition");
        final GetShipHistoryPositionRes result = new GetShipHistoryPositionRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {

            long startTimeLong = 0;
            long endTimeLong = 0;

            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(carNumber, "carNumber is not blank");

                if (queryType == 1) {
                    startTimeLong = System.currentTimeMillis() - 86400000;
                    endTimeLong = System.currentTimeMillis();
                } else if (queryType == 2) {
                    AssertUtil.isNotBlank(startTime, "开始时间不能为空");
                    AssertUtil.isTrue(AssertUtil.isValidDate(startTime), BizErrorCode.PARAM_ERROR, "开始时间不是一个标准的时间格式");
                    AssertUtil.isNotBlank(endTime, "结束时间不能为空");
                    AssertUtil.isTrue(AssertUtil.isValidDate(endTime), BizErrorCode.PARAM_ERROR, "结束时间不是一个标准的时间格式");
                    startTimeLong = MapDateUitls.convertTimeToLong(startTime);
                    endTimeLong = MapDateUitls.convertTimeToLong(endTime);
                } else {
                    throw new BizException(BizErrorCode.PARAM_ERROR, "queryType取值不正确");
                }

            }

            @Override
            public void doService() throws Exception {
                Query query = new Query();
                Criteria criteria = Criteria.where("_id").lt(endTimeLong).gte(startTimeLong);
                query.addCriteria(criteria);
                result.setHistoryPositionModels(mongoTemplate.find(
                        query, HistoryPositionModel.class, carNumber + MongoConstant.CAR_POSITION_HISTORY_SPACE));
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "单兵轨迹数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "carNumber", value = "车辆编号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "queryType", value = "1 轨迹回放 2 历史轨迹，1类型，时间不用传，直接从现在的时间往前推24个小时", required = true, paramType = "query"),
            @ApiImplicitParam(name = "startTime", value = "查询的开始时间", required = true, paramType = "query"),
            @ApiImplicitParam(name = "endTime", value = "查询的结束时间", required = true, paramType = "query")
    })
    @GetMapping("soldier/position/history")
    public GetSoldierHistoryPositionRes getSoldierHistoryPosition(@RequestParam String soldierNumber, @RequestParam("queryType") int queryType,
                                                                  @RequestParam("startTime") String startTime, @RequestParam("endTime") String endTime) {
        log.info("单兵轨迹数据--getSoldierHistoryPosition");
        final GetSoldierHistoryPositionRes result = new GetSoldierHistoryPositionRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {

            long startTimeLong = 0;
            long endTimeLong = 0;

            @Override
            public void check() throws Exception {
                AssertUtil.isNotBlank(soldierNumber, "soldierNumber is not blank");

                if (queryType == 1) {
                    startTimeLong = System.currentTimeMillis() - 86400000;
                    endTimeLong = System.currentTimeMillis();
                } else if (queryType == 2) {
                    AssertUtil.isNotBlank(startTime, "开始时间不能为空");
                    AssertUtil.isTrue(AssertUtil.isValidDate(startTime), BizErrorCode.PARAM_ERROR, "开始时间不是一个标准的时间格式");
                    AssertUtil.isNotBlank(endTime, "结束时间不能为空");
                    AssertUtil.isTrue(AssertUtil.isValidDate(endTime), BizErrorCode.PARAM_ERROR, "结束时间不是一个标准的时间格式");
                    startTimeLong = MapDateUitls.convertTimeToLong(startTime);
                    endTimeLong = MapDateUitls.convertTimeToLong(endTime);
                } else {
                    throw new BizException(BizErrorCode.PARAM_ERROR, "queryType取值不正确");
                }
            }

            @Override
            public void doService() throws Exception {
                Query query = new Query();
                Criteria criteria = Criteria.where("_id").lt(endTimeLong).gte(startTimeLong);
                query.addCriteria(criteria);
                result.setHistoryPositionModels(mongoTemplate.find(
                        query, HistoryPositionModel.class, soldierNumber + MongoConstant.SOLIDER_POSITION_HISTORY_SPACE));
                result.setSuccess(true);
            }
        });
    }

    @ApiOperation(value = "车辆列表数据", notes = "车辆列表数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mapCarResourceListReq", required = true, dataType = "MapCarResourceListReq")
    })
    @PostMapping("car/list")
    public MapCarResourceListRes mapCarResourceList(@RequestBody MapCarResourceListReq mapCarResourceListReq) {
        log.info("车辆列表数据--mapCarResourceList");
        final MapCarResourceListRes result = new MapCarResourceListRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {

                AssertUtil.isTrue(mapCarResourceListReq.getCurrentPage() > 0, BizErrorCode.PARAM_ERROR, "pageSize必须大于0");
            }

            @Override
            public void doService() throws Exception {
                PageQueryMapCarCondition pageQueryMapCarCondition =
                        new PageQueryMapCarCondition(mapCarResourceListReq.getCurrentPage(), mapCarResourceListReq.getPageSize());
                pageQueryMapCarCondition.setCarQuery(mapCarResourceListReq.getCarQuery());

                // 查询数据
                List<CarResource> carResources = carResourceService.mapCarRecords(pageQueryMapCarCondition);
                result.setMapCarResourceListInfos(MapCarResourceConvertor.carResourceListToMapCarResourceListInfoList(carResources));
                result.setTotalRecords(carResourceService.mapCarRecordsTotal(pageQueryMapCarCondition));
                result.setSuccess(true);
            }
        });
    }

//    @ApiOperation(value = "车辆当前位置信息", notes = "点击车辆列表数据用于定位车辆位置")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "carNumber", paramType = "path", value = "车辆编号", required = true)
//    })
//    @GetMapping("car/position/{carNumber}")
//    public GetCarCurrentPositionRes getCarCurrentPosition(@PathVariable("carNumber") String carNumber) {
//        log.info("获取车辆当前位置--getCarCurrentPosition carNumber = {}", carNumber);
//        final GetCarCurrentPositionRes result = new GetCarCurrentPositionRes();
//        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
//            @Override
//            public void check() throws Exception {
//                AssertUtil.isNotBlank(carNumber, "车辆编号不能为空");
//            }
//
//            @Override
//            public void doService() throws Exception {
//
//                AssertUtil.isTrue(redisTemplate.opsForHash().hasKey(
//                        CacheConstant.REDIS_MAP_CURRENT_CAR_SPACE, carNumber),
//                        BizErrorCode.SYSTEM_ERROR, "未查找到当前车辆的最新坐标数据");
//
//                String carObj = (String) redisTemplate.opsForHash().get(
//                        CacheConstant.REDIS_MAP_CURRENT_CAR_SPACE, carNumber);
//
//                MapCommonModel mapCommonModel = objectMapper.readValue(carObj, MapCommonModel.class);
//                if (mapCommonModel != null) {
//                    result.setLatitude(mapCommonModel.getLatitude());
//                    result.setLongitude(mapCommonModel.getLongitude());
//                }
//                result.setSuccess(true);
//            }
//        });
//    }

    @ApiOperation(value = "单兵列表数据", notes = "单兵列表数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mapSoldierResourceListReq", required = true, dataType = "MapSoldierResourceListReq")
    })
    @PostMapping("soldier/list")
    public MapSoldierResourceListRes mapShipResourceList(@RequestBody MapSoldierResourceListReq mapSoldierResourceListReq) {
        log.info("单兵列表数据--mapShipResourceList");
        final MapSoldierResourceListRes result = new MapSoldierResourceListRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {

                AssertUtil.isTrue(mapSoldierResourceListReq.getCurrentPage() > 0, BizErrorCode.PARAM_ERROR, "pageSize必须大于0");
            }

            @Override
            public void doService() throws Exception {
                PageQueryMapSoldierCondition pageQueryMapSoldierCondition =
                        new PageQueryMapSoldierCondition(mapSoldierResourceListReq.getCurrentPage(), mapSoldierResourceListReq.getPageSize());
                pageQueryMapSoldierCondition.setSoldierNumber(mapSoldierResourceListReq.getSoldierNumber());
                pageQueryMapSoldierCondition.setSoldierType(mapSoldierResourceListReq.getSoldierType());
                // 查询数据
                List<SingleSoldierResource> singleSoldierResources = singleSoldierResourceService.mapSoldierRecords(pageQueryMapSoldierCondition);
                result.setMapSoldierResourceListInfos(MapSoldierResourceConvertor.singleSoldierResourceListToMapSoldierResourceListInfoList(singleSoldierResources));
                result.setTotalRecords(singleSoldierResourceService.mapSoldierRecordsTotal(pageQueryMapSoldierCondition));
                result.setSuccess(true);
            }
        });
    }

//    @ApiOperation(value = "单兵列表数据当前位置", notes = "点击单兵列表数据用于定位车辆位置")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "soldierNumber", paramType = "path", value = "单兵编号", required = true)
//    })
//    @GetMapping("soldier/position/{soldierNumber}")
//    public GetCarCurrentPositionRes getSoldierCurrentPosition(@PathVariable("soldierNumber") String soldierNumber) {
//        log.info("单兵列表数据当前位置--getCarCurrentPosition carNumber = {}", soldierNumber);
//        final GetCarCurrentPositionRes result = new GetCarCurrentPositionRes();
//        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
//            @Override
//            public void check() throws Exception {
//                AssertUtil.isNotBlank(soldierNumber, "单兵编号不能为空");
//            }
//
//            @Override
//            public void doService() throws Exception {
//
//                AssertUtil.isTrue(redisTemplate.opsForHash().hasKey(
//                        CacheConstant.REDIS_MAP_CURRENT_SOLDIER_SPACE, soldierNumber),
//                        BizErrorCode.SYSTEM_ERROR, "未查找到当前单兵的最新坐标数据");
//
//                String soilderObj = (String) redisTemplate.opsForHash().get(
//                        CacheConstant.REDIS_MAP_CURRENT_SOLDIER_SPACE, soldierNumber);
//
//                MapCommonModel mapCommonModel = objectMapper.readValue(soilderObj, MapCommonModel.class);
//                if (mapCommonModel != null) {
//                    result.setLatitude(mapCommonModel.getLatitude());
//                    result.setLongitude(mapCommonModel.getLongitude());
//                }
//                result.setSuccess(true);
//            }
//        });
//    }

    @ApiOperation(value = "无人机列表数据", notes = "无人胡列表数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mapUavResourceListReq", required = true, dataType = "MapUavResourceListReq")
    })
    @PostMapping("uav/list")
    public MapUavResourceListRes mapShipResourceList(@RequestBody MapUavResourceListReq mapUavResourceListReq) {
        log.info("无人机列表数据--mapUavResourceListReq");
        final MapUavResourceListRes result = new MapUavResourceListRes();
        return serviceExecuteTemplate.executeService(result, new ServiceCallBack() {
            @Override
            public void check() throws Exception {

                AssertUtil.isTrue(mapUavResourceListReq.getCurrentPage() > 0, BizErrorCode.PARAM_ERROR, "pageSize必须大于0");
            }

            @Override
            public void doService() throws Exception {
                PageQueryMapUavCondition pageQueryMapUavCondition =
                        new PageQueryMapUavCondition(mapUavResourceListReq.getCurrentPage(), mapUavResourceListReq.getPageSize());
                pageQueryMapUavCondition.setUavNumber(mapUavResourceListReq.getUavNumber());
                // 查询数据
                List<MapUavResource> mapUavResources = uavResourceService.queryMapUavListRecords(pageQueryMapUavCondition);
                result.setUavList(UavResourceConvertor.mapUavResourceListsInfoToMapUavResources(mapUavResources));
                result.setTotalRecords(uavResourceService.queryMapUavListRecordCount(pageQueryMapUavCondition));
                result.setSuccess(true);
            }
        });
    }

}
